package br.com.velp.sudecap.daoimpl;

import br.com.velp.sudecap.dao.ImovelDAO;
import br.com.velp.sudecap.dto.ImovelParametrosConsultaDTO;
import br.com.velp.sudecap.entidade.Imovel;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.sql.JoinType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

/**
 * <sumario> <objetivo> "Rastreabilidade" </objetivo> <autor> EDUARDO SANTOS DE
 * OLIVEIRA </autor> <versao>1.0.0.0</versao> <data_criacao> 17.10.2012
 * </data_criacao> <data_ultima_alteracao> N/A </data_ultima_alteracao>
 * <requisitos_afetados> RF006.03 - Relacionar Decretos x Imóveis
 * </requisitos_afetados> <descricao> Implementação da Interface Responsável
 * Pelas Operações de CRUD Referentes ao Contexto de Cartorios </descricao>
 * </sumario>
 */
@Repository("imovelDAO")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class ImovelDAOImpl implements ImovelDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public Long salvar(Imovel value) {
	Long id = (Long) getSession().save(value);
	getSession().flush();
	return id;
    }

    @Override
    public void atualizar(Imovel value) {
	getSession().update(value);
	getSession().flush();
    }

    @Override
    public Imovel obterPorId(Long id) {
	return (Imovel) getSession().get(Imovel.class, id);
    }

    @Override
    public void excluir(Imovel value) {
	getSession().delete(value);
	getSession().flush();
    }

    @Override
    public int contarImoveis(ImovelParametrosConsultaDTO parametros) {
	Criteria criteria = getSession().createCriteria(Imovel.class);
	criteria.setProjection(Projections.countDistinct("id"));
	adicionarFiltrosConsulta(criteria, parametros);
	return ((Long) criteria.uniqueResult()).intValue();
    }

    @Override
    public List<Imovel> buscarImoveisPaginados(int firstResult, int maxResults,
	    ImovelParametrosConsultaDTO parametros, Order order) {
	Criteria criteria = getSession().createCriteria(Imovel.class);
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
	adicionarFiltrosConsulta(criteria, parametros);
	if (firstResult > 0) {
	    criteria.setFirstResult(firstResult);
	}
	if (maxResults > 0) {
	    criteria.setMaxResults(maxResults);
	}
	if (order != null) {
	    criteria.addOrder(order);
	} else {
	    criteria.addOrder(Order.asc("bairro"));
	}
	return criteria.list();
    }

    public Session getSession() {
	return this.sessionFactory.getCurrentSession();
    }

    private void adicionarFiltrosConsulta(Criteria criteria, ImovelParametrosConsultaDTO parametros) {
	
	criteria.createAlias("imoveisEmpreendimentos", "imovelEmpreendimento", JoinType.LEFT_OUTER_JOIN);
	criteria.createAlias("imovelEmpreendimento.empreendimento", "empreendimento", JoinType.LEFT_OUTER_JOIN);	
	
	if(StringUtils.isNotBlank(parametros.getCodigoXPLAN())){
	    criteria.add(Restrictions.eq("empreendimento.codigoXplan", parametros.getCodigoXPLAN()));
	}
	if (StringUtils.isNotBlank(parametros.getEmpreendimento())) {
	    criteria.add(Restrictions.ilike("empreendimento.nome", parametros.getEmpreendimento(), MatchMode.ANYWHERE));
	}
	if (StringUtils.isNotBlank(parametros.getBairro())) {
	    criteria.add(Restrictions.ilike("bairro", parametros.getBairro(), MatchMode.ANYWHERE));
	}
	if (StringUtils.isNotBlank(parametros.getCt())) {
	    criteria.add(Restrictions.eq("ct", parametros.getCt()));
	}
	if(StringUtils.isNotBlank(parametros.getCtmSetor())){
	    criteria.add(Restrictions.eq("ctmSetor", parametros.getCtmSetor()));
	}
	if(StringUtils.isNotBlank(parametros.getCtmQuadra())){
	    criteria.add(Restrictions.eq("ctmQuadra", parametros.getCtmQuadra()));
	}
	if(StringUtils.isNotBlank(parametros.getCtmImovel())){
	    criteria.add(Restrictions.eq("ctmImovel", parametros.getCtmImovel()));
	}
	if (StringUtils.isNotBlank(parametros.getLogradouro())) {
	    criteria.add(Restrictions.ilike("logradouro", parametros.getLogradouro(), MatchMode.ANYWHERE));
	}
	if (StringUtils.isNotBlank(parametros.getLote())) {
	    criteria.add(Restrictions.eq("lote", parametros.getLote()));
	}
	if (StringUtils.isNotBlank(parametros.getPessoa())) {
//	    criteria.add(Restrictions.ilike("pessoa", parametros.getPessoa(), MatchMode.ANYWHERE));
	}
	if (StringUtils.isNotBlank(parametros.getQuadra())) {
	    criteria.add(Restrictions.eq("quadra", parametros.getQuadra()));
	}
	if (parametros.getIdRegional() != null) {
	    criteria.add(Restrictions.eq("regional.id", parametros.getIdRegional()));
	}
	if (parametros.getImoveisNotIn() != null && !parametros.getImoveisNotIn().isEmpty()) {
	    criteria.add(Restrictions.not(Restrictions.in("id", parametros.getImoveisNotIn())));
	}
	
    }
}
